<template>
	<e-transition :show="props.show">
		<view class="e-skeleton" ref="skeletonElRef" :class="[is('fixed', props?.fixed)]">
			<e-status-bar v-if="props.fixed && props.safeAreaInsetTop"></e-status-bar>
			<slot></slot>
			<e-safe-bottom v-if="props.fixed && props.safeAreaInsetBottom"></e-safe-bottom>
		</view>
	</e-transition>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import mpMixin from '../../libs/mixin/mpMixin';
/**
 * skeleton 骨架屏
 * @description 骨架屏
 * @tutorial https://www.uviewui.com/components/skeleton.html
 * @property {Boolean}			show				是否展示弹窗 (默认 false )
 * @property {Boolean}			animate				是否开启动画效果 (默认 true )
 * @property {Object}			config				配置项
 * @property {String | Number}	zIndex				层级 （默认 10080 ）
 * @property {Boolean}			safeAreaInsetBottom	是否为iPhoneX留出底部安全距离 （默认 true ）
 * @property {Boolean}			safeAreaInsetTop	是否留出顶部安全距离（状态栏高度） （默认 false ）
 * @property {Object}			customStyle			组件的样式，对象形式
 * @example <e-skeleton :show="show"><text>出淤泥而不染，濯清涟而不妖</text></e-skeleton>
 */
export default defineComponent({
	name: 'e-skeleton',
	mixins: [mpMixin]
});
</script>

<script lang="ts" setup>
import { ref, reactive, watch, toRefs, provide, onMounted } from 'vue';
import { useDefaultProps } from '../../libs/hooks';
import { skeletonProps } from './props';
import componentsProps from '../../libs/config/componentsProps';
import type {  SkeletonProps } from '../../libs/config/propsType';
import { skeletonContextKey } from '../../libs/tokens';
import { useNamespace } from '../../libs/hooks';
import { sleep } from '../../libs/utils';



const { skeleton: skeletonDefaultProps } = toRefs(componentsProps);

const _props = defineProps(skeletonProps);

const props = useDefaultProps<SkeletonProps>(_props, skeletonDefaultProps);

const { is } = useNamespace('skeleton');

// #ifdef APP-NVUE
let animation:any
const skeletonElRef = ref();
const startNvueAnimation = async () => {
	// 为了让opacity:1的状态保持一定时间，这里做一个延时
	await sleep(500);

	skeletonElRef.value &&
		animation.transition(
			skeletonElRef.value,
			{
				styles: {
					opacity: 0.5
				},
				duration: 600
			},
			() => {
				// 这里无需判断是否loading和开启动画状态，因为最终的状态必须达到opacity: 1，否则可能
				// 会停留在opacity: 0.5的状态中
				animation.transition(
					skeletonElRef.value,
					{
						styles: {
							opacity: 1
						},
						duration: 600
					},
					() => {
						// 只有在loading中时，才执行动画
						props.value.show && props.value.animate && startNvueAnimation();
					}
				);
			}
		);
};
// #endif
const init = () => {
	// #ifdef APP-NVUE
	props.value.animate && startNvueAnimation();
	// #endif
	// #ifdef APP-NVUE
	animation = uni.requireNativePlugin('animation');
	// #endif
};

watch(
	() => props.value.show,
	(v) => {
		if (v) {
			init();
		}
	}
);

onMounted(() => {
	if (props.value.show) {
		init();
	}
});

provide(
	skeletonContextKey,
	reactive({
		props
	})
);
</script>

<style lang="scss" scoped>
@import '../../libs/theme/skeleton.scss';
</style>
